package com.finance.report.service;

import com.finance.base.enums.CalculateTypeEnum;
import com.finance.base.enums.MajorTypeEnum;
import com.finance.base.enums.StateEnum;
import com.finance.report.bean.pojo.LogisticsData;
import com.finance.report.bean.pojo.ManSalary;
import com.finance.report.bean.pojo.ManSalaryDetail;
import com.finance.util.DateUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by CBWL on 2017/6/21.
 */
@Component
public class ManSalaryCommitter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IManSalaryService manSalaryService;

    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void updateUserFee(LogisticsData logisticsData, BigDecimal fee, CalculateTypeEnum calculateTypeEnum, MajorTypeEnum majorTypeEnum) throws Exception {
        this.logger.info("开始更新updateUserFee{}", logisticsData.getWaybillNum());
        String month = this.genMonth(logisticsData);
        ManSalary manSalary = this.manSalaryService.getByUserCodeRandom(logisticsData.getPostmanNo(), month);
        if(manSalary == null){
            this.logger.info("锁{}员工工资数据无{} 需新增", this.genMonth(logisticsData) + logisticsData.getPostmanNo(), logisticsData.getWaybillNum());
            manSalary = this.genManSalary(logisticsData, fee, calculateTypeEnum,majorTypeEnum);
            this.logger.info("处理后的月报表信息：{}", JSONObject.fromObject(manSalary));
            this.logger.info("员工工资数据无{}", logisticsData.getWaybillNum());
            ManSalaryDetail manSalaryDetail = this.genManSalaryDetail(logisticsData, fee, calculateTypeEnum,majorTypeEnum);
            List<ManSalaryDetail> list = new ArrayList<ManSalaryDetail>();
            list.add(manSalaryDetail);
            manSalary.setManSalaryDetailList(list);
            this.manSalaryService.addManSalaryWithDetail(manSalary);
            this.logger.info("锁{}新增成功", String.valueOf(this.genMonth(logisticsData) + logisticsData.getPostmanNo()));
            this.logger.info("员工工资数据无{} 已新增明 月报表信息：{}", logisticsData.getWaybillNum(), JSONObject.fromObject(manSalary));
        }else{
            this.logger.info("员工工资数据{} 需更新 月报表信息：{}", logisticsData.getWaybillNum(), JSONObject.fromObject(manSalary));
            manSalary = this.freshManSalary(manSalary, fee, majorTypeEnum);
            ManSalaryDetail manSalaryDetail = this.manSalaryService.getDetailBySupplierCode(manSalary, logisticsData.getSupplierCode());
            if(manSalaryDetail == null){
                this.logger.info("员工工资数据{} 无明细 需新增 月报表明细信息", logisticsData.getWaybillNum());
                manSalaryDetail = this.genManSalaryDetail(logisticsData, fee, calculateTypeEnum,majorTypeEnum);
                this.logger.info("处理后的月报表明细信息：{}", JSONObject.fromObject(manSalaryDetail));
                this.manSalaryService.addManSalaryDetail(manSalaryDetail);
                this.logger.info("员工工资数据{} ", logisticsData.getWaybillNum());
            }else{
                this.logger.info("员工工资数据{} 明细 需更新", logisticsData.getWaybillNum());
                manSalaryDetail = this.freshManSalaryDetail(manSalaryDetail, fee, calculateTypeEnum, majorTypeEnum);
                this.logger.info("处理后的月报表明细信息：{}", JSONObject.fromObject(manSalaryDetail));
                this.manSalaryService.updateManSalaryDetail(manSalaryDetail, logisticsData.getWaybillNum());
                this.logger.info("员工工资数据{} 已明细更新", logisticsData.getWaybillNum());
            }
            this.manSalaryService.updateManSalary(manSalary, logisticsData.getWaybillNum());
            this.logger.info("最终更新的月报表信息：{}", JSONObject.fromObject(manSalary));
            this.logger.info("员工工资数据{} 已更新", logisticsData.getWaybillNum());
        }
    }

    public String genMonth(LogisticsData logisticsData){
        return DateUtil.dateFormat(logisticsData.getSignTime(),"yyyy-MM");
    }

    private ManSalary freshManSalary(ManSalary manSalary, BigDecimal fee, MajorTypeEnum majorTypeEnum){
        BigDecimal supplierFee = manSalary.getSupplierFee();
        supplierFee = supplierFee.add(fee);
        manSalary.setSupplierFee(supplierFee);
        BigDecimal totalFee = manSalary.getTotalFee();
        totalFee = totalFee.add(fee);
        manSalary.setTotalFee(totalFee);

        if(majorTypeEnum == MajorTypeEnum.MAJOR){
            BigDecimal majorFee = manSalary.getMajorFeeTotal() == null ? fee : manSalary.getMajorFeeTotal().add(fee);
            manSalary.setMajorFeeTotal(majorFee);
            int majorCount = manSalary.getMajorTotal() == null ? 0 : manSalary.getMajorTotal();
            manSalary.setMajorTotal(majorCount + 1);
        }else if(majorTypeEnum == MajorTypeEnum.DRAG){
            BigDecimal minorFee = manSalary.getMinorFeeTotal() == null ? fee : manSalary.getMinorFeeTotal().add(fee);
            manSalary.setMinorFeeTotal(minorFee);
            int minorCount = manSalary.getMinorTotal() == null ? 0 : manSalary.getMinorTotal();
            manSalary.setMinorTotal(minorCount + 1);
        }
        this.logger.info("刷新后manSalary：{}", String.valueOf(manSalary));
        return manSalary;
    }

    private ManSalary genManSalary(LogisticsData logisticsData, BigDecimal fee, CalculateTypeEnum calculateTypeEnum, MajorTypeEnum majorTypeEnum) {
        ManSalary manSalary = new ManSalary();
        manSalary.setUserCode(logisticsData.getPostmanNo());
        manSalary.setSalaryMonth(this.genMonth(logisticsData));
        manSalary.setBaseFee(null);
        manSalary.setVersion(0);
        manSalary.setTotalFee(fee);
        manSalary.setSupplierFee(fee);
        manSalary.setManSalaryDetailList(new ArrayList<ManSalaryDetail>());
        if(majorTypeEnum == MajorTypeEnum.MAJOR){
            manSalary.setMajorFeeTotal(fee);
            manSalary.setMajorTotal(1);
            manSalary.setMinorFeeTotal(new BigDecimal(0));
            manSalary.setMinorTotal(0);
        }else if(majorTypeEnum == MajorTypeEnum.DRAG){
            manSalary.setMinorFeeTotal(fee);
            manSalary.setMinorTotal(1);
            manSalary.setMajorFeeTotal(new BigDecimal(0));
            manSalary.setMajorFeeTotal(new BigDecimal(0));
        }
        this.logger.info("组装manSalary：{}", String.valueOf(manSalary));
        return  manSalary;
    }

    private ManSalaryDetail genManSalaryDetail(LogisticsData logisticsData, BigDecimal fee, CalculateTypeEnum calculateTypeEnum, MajorTypeEnum majorTypeEnum){
        ManSalaryDetail manSalaryDetail = new ManSalaryDetail();
        manSalaryDetail.setSupplierCode(logisticsData.getSupplierCode());
        manSalaryDetail.setSalaryMonth(this.genMonth(logisticsData));
        manSalaryDetail.setCalculateType(calculateTypeEnum.getValue());
        manSalaryDetail.setUserCode(logisticsData.getPostmanNo());
        manSalaryDetail.setState(StateEnum.Valid.getState());
        manSalaryDetail.setVersion(0);
        if(majorTypeEnum == MajorTypeEnum.MAJOR){
            manSalaryDetail.setMajorFee(fee);
            manSalaryDetail.setMajorCount(1);
            manSalaryDetail.setTotalFee(fee);
            manSalaryDetail.setMinorFee(new BigDecimal(0));
            manSalaryDetail.setMinorCount(0);
        }else if(majorTypeEnum == MajorTypeEnum.DRAG){
            manSalaryDetail.setMinorFee(fee);
            manSalaryDetail.setMinorCount(1);
            manSalaryDetail.setTotalFee(fee);
            manSalaryDetail.setMajorFee(new BigDecimal(0));
            manSalaryDetail.setMajorCount(0);
        }
        this.logger.info("组装ManSalaryDetail：{}", String.valueOf(manSalaryDetail));
        return manSalaryDetail;
    }

    private ManSalaryDetail freshManSalaryDetail(ManSalaryDetail manSalaryDetail, BigDecimal fee, CalculateTypeEnum calculateTypeEnum, MajorTypeEnum majorTypeEnum){
        manSalaryDetail.setCalculateType(calculateTypeEnum.getValue());
        BigDecimal totalFee = manSalaryDetail.getTotalFee() == null ? fee : manSalaryDetail.getTotalFee();
        totalFee = totalFee.add(fee);
        manSalaryDetail.setTotalFee(totalFee);
        if(majorTypeEnum == MajorTypeEnum.MAJOR){
            BigDecimal majorFee = manSalaryDetail.getMajorFee() == null ? fee : manSalaryDetail.getMajorFee().add(fee);
            int majorCount = manSalaryDetail.getMajorCount() ==  null ? 0 : manSalaryDetail.getMajorCount();
            manSalaryDetail.setMajorFee(majorFee);
            manSalaryDetail.setMajorCount(majorCount + 1);
        }else if(majorTypeEnum == MajorTypeEnum.DRAG){
            BigDecimal minorFee = manSalaryDetail.getMinorFee() == null ? fee : manSalaryDetail.getMinorFee().add(fee);
            int minorCount = manSalaryDetail.getMinorCount() == null ? 0 : manSalaryDetail.getMinorCount();
            manSalaryDetail.setMinorFee(minorFee);
            manSalaryDetail.setMinorCount(minorCount + 1);
        }
        this.logger.info("刷新ManSalaryDetail：{}", String.valueOf(manSalaryDetail));
        return manSalaryDetail;
    }

}
